package com.itic.appbase.applications.mangodb.impl;

import java.lang.reflect.ParameterizedType;
import java.util.Collection;
import java.util.List;
import java.util.Map;

import org.apache.poi.ss.formula.functions.T;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.mongodb.core.MongoTemplate;
import org.springframework.data.mongodb.core.query.Criteria;
import org.springframework.data.mongodb.core.query.Query;
import org.springframework.data.mongodb.core.query.Update;
import org.springframework.stereotype.Repository;

import com.itic.appbase.applications.mangodb.IMongodbDao;

@Repository
public class MongodbDao<T> implements IMongodbDao<T>{
	
	@Autowired
	private MongoTemplate mongoTemplate;
	
	private Class<T> entityClass;
	
	private Class<T> getClazz(){  
	    if (entityClass==null) {  
	    	entityClass=(Class<T>)(((ParameterizedType)this.getClass().getGenericSuperclass()).getActualTypeArguments()[0]);  
	    }
	    return entityClass;  
	} 
	@Override
	public void insert(T t) {
		this.mongoTemplate.insert(t);
	}

	@Override
	public T findOne(String id) {
		return (T) this.mongoTemplate.findOne(new Query(Criteria.where("id").is(id)),getClazz());
	}
	
	@Override
	public List<T> findAll() {
		return (List<T>) mongoTemplate.find(new Query(),getClazz());   
	}
	@Override
	public void removeOne(String id) {
		Criteria criteria = Criteria.where("id").in(id);   
        if(criteria == null){   
             Query query = new Query(criteria);   
             if(query != null && mongoTemplate.findOne(query,getClazz()) != null)   
            	 mongoTemplate.remove(mongoTemplate.findOne(query,getClazz()));   
        } 
	}
	
	@Override
	public void removeAll() {
		List<T> list = this.findAll();   
        if(list != null){   
            for(T t : list){   
            	mongoTemplate.remove(t);   
            }   
        }   
	}
	@Override
	public void update(String id,Map<String, Object> params) {
		Query query = Query.query(Criteria.where("id").is(id));
		Update update = new Update();
		this.setParameters(update, params);
		mongoTemplate.updateMulti(query, update,getClazz());
	}
	
	@Override
	public void saveOrUpdate(String id, Map<String, Object> params) {
		Query query = Query.query(Criteria.where("id").is(id));
		Update update = new Update();
		this.setParameters(update, params);
		mongoTemplate.upsert(query, update,getClazz());
		
	}
	
	private void setParameters(Update update,Map<String,Object> params){
		if(params!=null&&!params.isEmpty()){
			for(String key:params.keySet()){
				if(params.get(key) instanceof Collection)
					update.set(key, (Collection)params.get(key));
				else if(params.get(key).getClass().isArray())
					update.set(key,(Object[])params.get(key));
				else
					update.set(key, params.get(key));
			}
		}
	}
}
